#ifndef __EKOS_KERNEL_H__
#define __EKOS_KERNEL_H__

/* This file is the internal header file for the microkernel of
 * EKOS-CC, should not be included outside the kernel directory */

/* The microkernel includes the base feature as a operating system
 * kernel */

#include <layout.h>
#include <mmu.h>
#include <types.h>
#include <x86.h>
#include <x86_lock.h>
#include <stdarg.h>
#include <error.h>
#include <syscall.h>
#include <trap.h>
#include <stab.h>
#include <proc.h>
#include <sysconf.h>

#include <string.h>
#include <ioif.h>
#include <parse.h>

#include "kernel.S.h"
#include "console.h"
#include "io.h"
#include "mem.h"
#include "sys.h"
#include "acpi.h"
#include "pic.h"
#include "lapic.h"
#include "ioapic.h"
#include "proc.h"
#include "task.h"
#include "kpipe.h"
#include "intr.h"
#include "elf.h"
#include "syscall.h"
#include "ipi.h"
#include "debug.h"

/* Defined in init.S and kernel.ld */
extern pdir_entry_t     init_vpd[];
extern spin_lock_t      init_vpd_lock[];
extern char				_start[], _text[], _text_end[], _bss[], _end[];
extern char             user_lib[], user_lib_end[];
extern struct stab_t	__STAB_BEGIN__[];		// Beginning of stabs table
extern struct stab_t	__STAB_END__[];			// End of stabs table
extern char				__STABSTR_BEGIN__[];	// Beginning of string table
extern char				__STABSTR_END__[];		// End of string table

/* Routines and symbols defined in kernel.S */
extern void *unknown_idt_gate[];
/* The entries of ISR interrupt */
extern void *isr[];
/* Entries of IRQ interrupt */
extern void *irq[];
/* KPIPE for system logging */
extern struct kpipe_t klog_pipe;

/* The interrupt entry defined in kernel.S */
/* The interrupt entry for syscall */
extern char syscall[];
/* For the yield call */
extern char int_yield[];
/* For return of kernel to user call */
extern char kcb_ret[];
/* For IPI */
extern char ipi[];

/* I/O delay? */
void delay();
/* Reboot the machine via asm */
void reboot();
/* Get current process id by the stack pointer */
int cur_proc_id();
/* Get current process structure */
// Disabled because of incurrect calculation of address
// struct proc_t *cur_proc();
void jump_user(void *addr, void *stack, uint32_t flags);
void call_user(void *addr, void *stack, uint32_t flags);

#define EKOS_NAME "EKOS-CC"
#define EKOS_VERSION "20101024"

#define BREAKPOINT __asm __volatile("xchg %bx, %bx")

#endif
